import pygame
import random
import const


class Block(pygame.sprite.Sprite):
    def __init__(self, x=1, y=1, width=40, color=const.BLOCK_COLOR):
        super().__init__()
        self.image = pygame.Surface([width, width])
        self.color = color
        self.image.fill(self.color)
        self.rect = self.image.get_rect()
        self.rect.x = x * (width + 1) + 1
        self.rect.y = y * (width + 1) + 1


class Wall(pygame.sprite.Sprite):
    def __init__(self, wh):
        super().__init__()
        self.image = pygame.Surface(wh)
        self.rect = self.image.get_rect()


class TetrisGame(object):
    def __init__(self):
        print("init...")
        pygame.init()
        self.speed_x, self.speed_y = 0, 1
        self.clock = pygame.time.Clock()

        self.left_edge = False
        self.right_edge = False

        self.active_blocks = pygame.sprite.Group()
        self.walls = pygame.sprite.Group()
        self.freeze_blocks = pygame.sprite.Group()

        self.bottom_wall = Wall((const.SCREEN_SIZE[0], const.BLOCK_WEIGHT))
        self.bottom_wall.rect.topleft = (0, const.SCREEN_SIZE[1])

        self.left_wall = Wall((const.BLOCK_WEIGHT, const.SCREEN_SIZE[1]))
        self.left_wall.rect.topright = (0, 0)

        self.right_wall = Wall((const.BLOCK_WEIGHT, const.SCREEN_SIZE[1]))
        self.right_wall.rect.topleft = (const.SCREEN_SIZE[0], 0)

        self.walls.add(self.left_wall, self.right_wall)
        self.freeze_blocks.add(self.bottom_wall)

        self.new_active_blocks()
        self.screen = pygame.display.set_mode(const.SCREEN_SIZE)

        pygame.time.set_timer(const.MOVE_DOWN_EVENT, 100)

    def start_game(self):
        print('starting game...')
        # 1、设置刷新帧率
        while True:
            self.clock.tick(const.FRAME_PER_SECOND)
            # 2
            self.__event_handler()
            # 3、碰撞检测
            # self.__check_collide()
            # 4、更新/绘制精灵组
            self.__update_sprites()
            # 5、更新显示
            pygame.display.update()

    def __event_handler(self):
        for event in pygame.event.get():
            # 判断是否退出游戏
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            elif event.type == const.MOVE_DOWN_EVENT:
                self.move_down()

        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_RIGHT]:
            self.speed_x = 1
        elif keys_pressed[pygame.K_LEFT]:
            self.speed_x = -1
        elif keys_pressed[pygame.K_DOWN]:
            self.speed_y += 1
        else:
            self.speed_x, self.speed_y = 0, 1
            # self.active_blocks.speed_y = 0

    def __update_sprites(self):
        self.screen.fill((0, 0, 0))
        self.update()
        self.active_blocks.update()
        self.active_blocks.draw(self.screen)
        self.freeze_blocks.update()
        self.freeze_blocks.draw(self.screen)

    def update_old(self):
        print(self.left_edge, self.right_edge)
        if (self.left_edge and self.speed_x < 0) or (self.right_edge and self.speed_x > 0):
            return
        self.left_edge, self.right_edge = False, False

        for sprite in self.active_blocks:
            sprite.rect.left += self.speed_x * (const.BLOCK_WEIGHT + 1)
            if sprite.rect.left <= 1:
                self.left_edge = True
            if sprite.rect.right >= const.SCREEN_SIZE[0] - 1:
                self.right_edge = True

    def update(self):
        right = self.speed_x
        if self.speed_x != 0:
            for sprite in self.active_blocks.sprites():
                sprite.rect.left += self.speed_x * (const.BLOCK_WEIGHT + 1)
        sprites = pygame.sprite.groupcollide(self.active_blocks, self.walls, False, False)
        # print(self.speed_x, len(sprites))
        if len(sprites) > 0:
            for sprite in self.active_blocks.sprites():
                sprite.rect.left -= self.speed_x * (const.BLOCK_WEIGHT + 1)

    def move_down(self):
        # print(len(self.active_blocks.sprites()), len(self.freeze_blocks.sprites()))
        for sp in self.active_blocks:
            sp.rect.y += (const.BLOCK_WEIGHT + 1)
        sprites = pygame.sprite.groupcollide(self.active_blocks, self.freeze_blocks, False, False)
        # print('发生碰撞的sprites:', sprites)
        if sprites:
            for sp in self.active_blocks:
                sp.rect.y -= (const.BLOCK_WEIGHT + 1)
            self.new_active_blocks()

    def new_active_blocks(self):
        # 清除活动方块中的所有方块
        for sp_ in self.active_blocks:
            sp_.image.fill(const.FREEZE_BLOCK_COLOR)
            self.freeze_blocks.add(sp_)
        self.active_blocks.empty()
        # 随机生成新的方块 TODO
        block_types = (const.BLOCK1, const.BLOCK2, const.BLOCK3, const.BLOCK4, const.BLOCK5)
        for tup_ in random.choice(block_types):
            block = Block(tup_[0], tup_[1])
            self.active_blocks.add(block)
